package net.jgrm.common.controller;

import net.jgrm.common.model.Result;
import net.jgrm.common.util.*;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;

import javax.servlet.http.HttpServletRequest;
import java.beans.PropertyEditorSupport;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;

/**
 * 基础控制器
 * 其他控制器继承此控制器获得日期字段类型转换和防止XSS攻击的功能，以及分页功能
 *
 * @author service-common
 * @date 2024-09-12
 */
public class BaseController {

    /**
     * 初始化数据绑定
     * 1. 将所有传递进来的String进行HTML编码，防止XSS攻击
     * 2. 将字段中Date类型转换为String类型
     *
     * @param binder 数据绑定器
     */
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        // Date 类型转换
        binder.registerCustomEditor(Date.class, new PropertyEditorSupport() {
            @Override
            public void setAsText(String text) {
                setValue(DateUtils.parseDate(text));
            }
        });

        // Timestamp 类型转换
        binder.registerCustomEditor(Timestamp.class, new PropertyEditorSupport() {
            @Override
            public void setAsText(String text) {
                Date date = DateUtils.parseDate(text);
                setValue(date == null ? null : new Timestamp(date.getTime()));
            }
        });
    }

    /**
     * 获取分页对象
     *
     * @param request HTTP请求对象
     * @return 分页对象
     */
    public <T> Page<T> getPage(HttpServletRequest request) {
        return getPage(request, null, null);
    }

    /**
     * 获取分页对象（带排序）
     *
     * @param request HTTP请求对象
     * @param orderBy 排序字段
     * @param order   排序方向
     * @return 分页对象
     */
    public <T> Page<T> getPage(HttpServletRequest request, String orderBy, Order order) {
        int pageNo = 1;       // 当前页码
        int pageSize = 20;    // 每页行数

        // 获取页码参数
        if (StringUtils.isNotEmpty(request.getParameter("page"))) {
            pageNo = Integer.valueOf(request.getParameter("page"));
        }
        if (StringUtils.isNotEmpty(request.getParameter("pageNumber"))) {
            pageNo = Integer.valueOf(request.getParameter("pageNumber"));
        }

        // 获取每页大小参数
        if (StringUtils.isNotEmpty(request.getParameter("rows"))) {
            pageSize = Integer.valueOf(request.getParameter("rows"));
        }
        if (StringUtils.isNotEmpty(request.getParameter("pageSize"))) {
            pageSize = Integer.valueOf(request.getParameter("pageSize"));
        }

        return new Page<>(pageNo, pageSize, orderBy, order);
    }

    /**
     * Page对象转PagingData对象
     *
     * @param page Page对象
     * @return PagingData对象
     */
    public <T> PagingData<T> getPagingData(Page<T> page) {
        PagingData<T> pagingData = new PagingData<>();
        Paging paging = new Paging();
        paging.setTotal(page.getTotalCount());
        paging.setPageSize(page.getPageSize());
        paging.setCurrent(page.getPageNo());
        pagingData.setList(page.getResult());
        pagingData.setPaging(paging);
        return pagingData;
    }

    /**
     * Page对象转PagingData对象（带DTO转换）
     *
     * @param pageInfo Page对象
     * @param dtoList  DTO列表
     * @return PagingData对象
     */
    public <S, T> PagingData<T> getPagingData(Page<S> pageInfo, List<T> dtoList) {
        Paging paging = new Paging();
        paging.setCurrent(pageInfo.getPageNo());
        paging.setPageSize(pageInfo.getPageSize());
        paging.setTotal(pageInfo.getTotalCount());

        PagingData<T> pageDTO = new PagingData<>();
        pageDTO.setPaging(paging);
        pageDTO.setList(dtoList);
        return pageDTO;
    }

    /**
     * 获取成功结果
     *
     * @return 成功结果
     */
    protected Result success() {
        return ResultUtils.getSuccessResult();
    }

    /**
     * 获取成功结果（带数据）
     *
     * @param data 数据
     * @return 成功结果
     */
    protected Result success(Object data) {
        return ResultUtils.getSuccessResult(data);
    }

    /**
     * 获取错误结果
     *
     * @return 错误结果
     */
    protected Result error() {
        return ResultUtils.getErrorResult();
    }

    /**
     * 获取错误结果（带消息）
     *
     * @param message 错误消息
     * @return 错误结果
     */
    protected Result error(String message) {
        return ResultUtils.getErrorResult(message);
    }


}